package com.example.forum.controller;

import com.example.forum.common.AppResult;
import com.example.forum.common.ResultCode;
import com.example.forum.config.AppConfig;
import com.example.forum.exception.ApplicationException;
import com.example.forum.model.Article;
import com.example.forum.model.Board;
import com.example.forum.model.User;
import com.example.forum.services.IArticleService;
import com.example.forum.services.IBoradService;
import com.example.forum.services.IUserService;
import com.example.forum.utils.MessageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.Calendar;
import java.util.stream.Collectors;


@RestController
@Slf4j
@Api(tags = "文章接口")
@RequestMapping("/article")
public class ArticleController {

    @Resource
    private IArticleService articleService;

    @Resource
    private IBoradService boardService;

    @Resource
    private IUserService userService;

    @Resource
    private MessageUtils messageUtils;

    /**
     *
     * @param request 当前登录的用户
     * @param boardId  板块Id
     * @param title  文章标题
     * @param content  文章正文
     * @param tags  文章标签
     * @param summary  文章摘要
     * @return
     */
   @PostMapping("/create")
   @ApiOperation("发布新文章")
   public AppResult<Long> create(HttpServletRequest request,  //获取当前用户id
                          @ApiParam("板块Id") @RequestParam("boardId") @NotNull Long boardId,
                           @ApiParam("文章标题") @RequestParam("title") @NotNull String title,
                           @ApiParam("文章正文") @RequestParam("content") @NotNull String content,
                           @ApiParam("文章标签") @RequestParam(value = "tags", required = false) String tags,
                           @ApiParam("文章摘要") @RequestParam(value = "summary", required = false) String summary){

       //校验当前用户是否禁言 and拿到当前用户id
       HttpSession session=request.getSession(false);
       User user= (User) session.getAttribute(AppConfig.USER_SESSION);
       if(user.getState()==1){
           //当前用户已经被禁言 无法添加文章
           return AppResult.failed(ResultCode.FAILED_USER_BANNED);
       }
       //校验板块id是否正确
       Board board=boardService.selectById(boardId);
       if(board==null||board.getDeleteState()==1||board.getState()==1){
           //板块校验失败
           log.warn(ResultCode.FAILED_BOARD_BANNED.toString());
           return AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE);
       }
       //拿到文章数据  构造文章内容
       Article article=new Article();
       article.setUserId(user.getId());  //用户Id
       article.setContent(content);  //正文
       article.setTitle(title);  //标题
       article.setBoardId(boardId);  //板块Id
       article.setTags(tags);  // 标签
       article.setSummary(summary);  // 摘要
       //执行调用方法
       articleService.create(article);
       
       // 返回文章ID
       return AppResult.success(article.getId());
   }


   @ApiOperation("获取帖子列表")
   @GetMapping("/getAllByBoardId")
   public AppResult<List<Article>> getAllByBoardId(@ApiParam("板块id") @RequestParam(value = "boardId",required = false)
                                                      @NotNull Long boardId){

       List<Article> articles;
        if(boardId==null){
            //查询所有文章数据
            articles = articleService.selectAll();
        }else {
            //如果有板块id 就需要查询指定板块的未被删除的所有帖子
            articles = articleService.getAllByBoardId(boardId);
        }
       //如果结果集为空 就创建空集合
       if(articles==null){
           articles=new ArrayList<>();
       }
       return AppResult.success(articles);
   }

   @ApiOperation("获取排序后的帖子列表")
   @GetMapping("/getSortedArticles")
   public AppResult<List<Article>> getSortedArticles(
        @ApiParam("板块id") @RequestParam(value = "boardId", required = false) Long boardId,
        @ApiParam("排序类型: new-最新, hot-最多浏览, comment-最多评论") @RequestParam(value = "sort", defaultValue = "new") String sortType,
        @ApiParam("时间范围: all-全部, day-今日, week-本周, month-本月") @RequestParam(value = "timeRange", defaultValue = "all") String timeRange,
        @ApiParam("页码") @RequestParam(value = "page", defaultValue = "1") Integer page,
        @ApiParam("每页数量") @RequestParam(value = "size", defaultValue = "10") Integer size,
        @ApiParam("搜索关键词") @RequestParam(value = "keyword", required = false) String keyword) {
       
       // 获取文章列表（改用包含用户信息的方法）
       List<Article> articles;
       if (boardId == null) {
           articles = articleService.selectAllWithUserInfo();
       } else {
           articles = articleService.getAllByBoardIdWithInfo(boardId);
       }
       
       if (articles == null) {
           articles = new ArrayList<>();
       }
       
       // 根据时间范围筛选
       if (!"all".equals(timeRange)) {
           Date currentDate = new Date();
           Calendar calendar = Calendar.getInstance();
           calendar.setTime(currentDate);
           
           if ("day".equals(timeRange)) {
               calendar.add(Calendar.DATE, -1);
           } else if ("week".equals(timeRange)) {
               calendar.add(Calendar.DATE, -7);
           } else if ("month".equals(timeRange)) {
               calendar.add(Calendar.MONTH, -1);
           }
           
           Date startDate = calendar.getTime();
           final Date filterDate = startDate;
           
           articles = articles.stream()
               .filter(article -> article.getCreateTime().after(filterDate))
               .collect(Collectors.toList());
       }
       
       // 根据关键词搜索
       if (keyword != null && !keyword.trim().isEmpty()) {
           String searchKeyword = keyword.toLowerCase();
           articles = articles.stream()
               .filter(article -> 
                   (article.getTitle() != null && article.getTitle().toLowerCase().contains(searchKeyword)) ||
                   (article.getContent() != null && article.getContent().toLowerCase().contains(searchKeyword)))
               .collect(Collectors.toList());
       }
       
       // 排序 - 首先根据置顶状态排序，然后再根据其他条件排序
       articles.sort((a1, a2) -> {
           // 首先根据置顶状态排序
           boolean isPinned1 = a1.getIsPinned() != null && a1.getIsPinned() == 1;
           boolean isPinned2 = a2.getIsPinned() != null && a2.getIsPinned() == 1;
           
           if (isPinned1 && !isPinned2) {
               return -1; // a1置顶，a2不置顶，a1排在前面
           } else if (!isPinned1 && isPinned2) {
               return 1;  // a1不置顶，a2置顶，a2排在前面
           } else {
               // 置顶状态相同，根据指定的排序方式进行排序
               if ("hot".equals(sortType)) {
                   // 按访问量排序
                   return Integer.compare(a2.getVisitCount(), a1.getVisitCount());
               } else if ("comment".equals(sortType)) {
                   // 按评论数排序
                   return Integer.compare(a2.getReplyCount(), a1.getReplyCount());
               } else {
                   // 默认按发布时间排序
                   return a2.getCreateTime().compareTo(a1.getCreateTime());
               }
           }
       });
       
       // 分页处理
       int total = articles.size();
       int start = (page - 1) * size;
       int end = Math.min(start + size, total);
       
       if (start >= total) {
           return AppResult.success(new ArrayList<>());
       }
       
       List<Article> pagedArticles = articles.subList(start, end);
       
       // 创建返回结果
       AppResult<List<Article>> result = AppResult.success(pagedArticles);
       result.setTotal(total);
       
       return result;
   }

   @ApiOperation("查询帖子详情")
   @GetMapping("/getDetails")
    public AppResult<Article> getDetails(HttpServletRequest request, @ApiParam("帖子id") @RequestParam("id") @NotNull Long id){
       // 获取文章详情
       Article article = articleService.selectDetailById(id);
       
       if(article == null){
           return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
       }
       
       // 获取当前登录对象（可能为空）
       HttpSession session = request.getSession(false);
       User user = null;
       if(session != null) {
           user = (User) session.getAttribute(AppConfig.USER_SESSION);
       }
       
       // 如果用户已登录，设置文章所有权标记
       if(user != null) {
           if(user.getId().equals(article.getUserId()) || user.getIsAdmin() == 1){
               article.setOwn(true);
           }
           
           // TODO: 这里可以添加其他登录用户才需要的信息，如是否已点赞等
       }
       
       // 移除重复的访问量增加：selectDetailById 方法已经增加了访问量
       // articleService.incrementVisitCount(id);
       
       //返回结果
       return AppResult.success(article);
   }

   @ApiOperation("修改文章内容")
   @PostMapping("/modify")
   public AppResult modify(HttpServletRequest request,
                          @ApiParam("文章id") @RequestParam("id") @NotNull Long id,
                          @ApiParam("文章标题") @RequestParam("title") @NotNull String title,
                          @ApiParam("文章内容") @RequestParam("content") @NotNull String content,
                          @ApiParam("板块ID") @RequestParam(value = "boardId", required = false) Long boardId,
                          @ApiParam("文章标签") @RequestParam(value = "tags", required = false) String tags,
                          @ApiParam("文章摘要") @RequestParam(value = "summary", required = false) String summary) {
       //获取当前登录用户，判断是否为作者
       HttpSession session = request.getSession(false);
       User user = (User) session.getAttribute(AppConfig.USER_SESSION);
       
       Article article = articleService.selectById(id);
       
       if(article == null || article.getDeleteState() == 1){
           return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
       }
       
       if(!article.getUserId().equals(user.getId()) && user.getIsAdmin() != 1){
           return AppResult.failed(ResultCode.FAILED_FORBIDDEN, "只有作者或管理员才能修改文章");
       }
       
       try {
           if(boardId != null){
               articleService.modifyWithBoard(id, title, content, boardId, tags, summary);
           } else {
               articleService.modify(id, title, content, tags, summary);
           }
           return AppResult.success();
       } catch (ApplicationException e) {
           log.error("修改文章失败", e);
           return e.getErrorResult();
       } catch (Exception e) {
           log.error("修改文章发生错误", e);
           return AppResult.failed(ResultCode.ERROR_SERVICES);
       }
   }

   @ApiOperation("删除文章")
   @PostMapping("/delete")
   public AppResult delete(HttpServletRequest request, 
                          @ApiParam("文章id") @RequestParam("id") @NotNull Long id) {
       // 获取当前登录用户
       HttpSession session = request.getSession(false);
       User user = (User) session.getAttribute(AppConfig.USER_SESSION);
       
       // 先获取文章详情
       Article article = articleService.selectDetailById(id);
       if(article == null) {
           return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
       }
       
       // 验证是否为作者或管理员
       if(article.getUserId() != user.getId() && user.getIsAdmin() != 1) {
           return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED, "只有文章作者或管理员可以删除文章");
       }
       
       // 执行删除
       try {
           articleService.deleteById(id);
           return AppResult.success();
       } catch (Exception e) {
           log.error("删除文章失败", e);
           return AppResult.failed(ResultCode.ERROR_SERVICES);
       }
   }

   @ApiOperation("点赞接口")
   @PostMapping("/thumbsUp")
   public AppResult thumbsUp(@ApiParam("帖子id") @RequestParam("id") @NotNull Long id,HttpServletRequest request){
       HttpSession session = request.getSession(false);
       User user= (User) session.getAttribute(AppConfig.USER_SESSION);
       //判断用户是否被禁言  如果禁言就无法操作
       if(user.getState()==1){
           return AppResult.failed(ResultCode.FAILED_USER_BANNED);
       }
       //判断帖子状态是否正常
       Article article = articleService.selectById(id);
       if(article==null||article.getDeleteState()==1){
           return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
       }
       if(article.getState()==1){
           return AppResult.failed(ResultCode.FAILED_ARTICLE_BANNED);
       }
       
       // 执行点赞操作
       articleService.thumbsUpById(id);
       
       // 发送点赞消息通知给文章作者（如果点赞者不是作者自己）
       if (!user.getId().equals(article.getUserId())) {
           try {
               messageUtils.sendLikeMessage(user, article.getUserId(), article.getId(), article.getTitle());
               log.info("已发送点赞消息通知: 用户{}点赞了文章{}", user.getId(), article.getId());
           } catch (Exception e) {
               // 消息发送失败不影响点赞操作
               log.error("发送点赞消息通知失败", e);
           }
       }
       
       //点赞成功
       return AppResult.success();
   }

   @ApiOperation("取消点赞接口")
   @PostMapping("/cancelThumbsUp")
   public AppResult cancelThumbsUp(@ApiParam("帖子id") @RequestParam("id") @NotNull Long id, HttpServletRequest request){
       HttpSession session = request.getSession(false);
       User user = (User) session.getAttribute(AppConfig.USER_SESSION);
       //判断用户是否被禁言  如果禁言就无法操作
       if(user.getState()==1){
           return AppResult.failed(ResultCode.FAILED_USER_BANNED);
       }
       //判断帖子状态是否正常
       Article article = articleService.selectById(id);
       if(article==null||article.getDeleteState()==1){
           return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
       }
       if(article.getState()==1){
           return AppResult.failed(ResultCode.FAILED_ARTICLE_BANNED);
       }
       articleService.cancelThumbsUpById(id);
       //取消点赞成功
       return AppResult.success();
   }

   @ApiOperation("查询用户帖子列表")
   @GetMapping("/getAllByUserId")
   public AppResult<List<Article>> getAllByUserId(
                                   @ApiParam("用户id") @RequestParam(value = "userId", required = false) Long userId,
                                   HttpServletRequest request) {
       //判断id 是否为空 如果为空 查询当前登录用户 不为空就查询指定的
       if(userId==null){
           HttpSession session=request.getSession(false);
           User user= (User) session.getAttribute(AppConfig.USER_SESSION);
           userId=user.getId();
       }
       
       // 从请求参数中获取分页信息，没有传入则使用默认值
       Integer page = 1;
       Integer size = 10;
       
       try {
           String pageStr = request.getParameter("page");
           String sizeStr = request.getParameter("size");
           
           if (pageStr != null && !pageStr.isEmpty()) {
               page = Integer.parseInt(pageStr);
               if (page < 1) {
                   page = 1;
               }
           }
           
           if (sizeStr != null && !sizeStr.isEmpty()) {
               size = Integer.parseInt(sizeStr);
               if (size < 1) {
                   size = 10;
               } else if (size > 100) {
                   size = 100; // 限制最大页面大小，防止资源滥用
               }
           }
       } catch (NumberFormatException e) {
           log.warn("解析分页参数失败，使用默认值: " + e.getMessage());
       }
       
       // 获取用户文章总数（用于分页）
       int total = articleService.countUserArticles(userId);
       
       // 查询指定的用户帖子列表（分页）
       List<Article> articles = articleService.selectByUserId(userId, page, size);
       
       // 创建包含分页信息的结果对象
       AppResult<List<Article>> result = AppResult.success(articles);
       result.setTotal(total);
       
       return result;
   }
   
   /**
    * 处理前端的文章编辑页面请求
    * 由于这是前后端分离的应用，前端实际通过API获取内容，
    * 这个方法主要是为了支持URL访问模式
    */
   @ApiOperation("文章编辑页面")
   @GetMapping("/edit/{id}")
   public AppResult<Article> getArticleForEdit(@ApiParam("文章id") @PathVariable("id") @NotNull Long id, 
                                           HttpServletRequest request) {
       // 复用getDetails方法获取文章详情，这样确保权限检查和数据填充逻辑一致
       return getDetails(request, id);
   }
}
